//////////////////////////////////////////////////////////////////////////////////	 
//本程序只供学习使用，未经作者许可，不得用于其它任何用途
//中景园电子
//店铺地址：http://shop73023976.taobao.com/?spm=2013.1.0.0.M4PqC2
//
//  文 件 名   : main.c
//  版 本 号   : v2.0
//  作    者   : HuangKai
//  生成日期   : 2014-0101
//  最近修改   : 
//  功能描述   : OLED 4接口演示例程(51系列)
//              说明: 
//              ----------------------------------------------------------------
//              GND    电源地
//              VCC  接5V或3.3v电源
//              D0   接PD6（SCL）
//              D1   接PD7（SDA）
//              RES  接PD4
//              DC   接PD5
//              CS   接PD3               
//              ----------------------------------------------------------------
// 修改历史   :
// 日    期   : 
// 作    者   : HuangKai
// 修改内容   : 创建文件
//版权所有，盗版必究。
//Copyright(C) 中景园电子2014/3/16
//All rights reserved
//******************************************************************************/

#include "oled.h"

extern void delay_us(unsigned long us);



//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127	
//[1]0 1 2 3 ... 127	
//[2]0 1 2 3 ... 127	
//[3]0 1 2 3 ... 127	
//[4]0 1 2 3 ... 127	
//[5]0 1 2 3 ... 127	
//[6]0 1 2 3 ... 127	
//[7]0 1 2 3 ... 127 			   


//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_CMD(unsigned char *ch,unsigned char n)
{	
	OLED_DC_Clr();		  
	OLED_CS_Clr();
//	for(i=0;i<n;i++)
//	{
//		OLED_WR_Byte(*ch++);
//	}
	OLED_WR_Buf(ch,n);
	OLED_CS_Set();
}

#define m_OLED_WR_CMD(A)	OLED_WR_CMD((unsigned char *)A,sizeof(A))

#define OLED_DAT_CS()	{OLED_DC_Set();OLED_CS_Clr();}



void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	unsigned char ch[3];
	
//	OLED_WR_CMD(0xb0+y);
//	OLED_WR_CMD((((x+2)&0xf0)>>4)|0x10);
//	OLED_WR_CMD(((x+2)&0x0f)); 

	ch[0]=0xb0+y;
	ch[1]=(((x+2)&0xf0)>>4)|0x10;
	ch[2]=((x+2)&0x0f);

	m_OLED_WR_CMD(ch);
}      	  

const unsigned char OLED_TB_Setup_column[]={0x21,0,127};
const unsigned char OLED_TB_Setup_page[]={0x22,0,7};
const unsigned char OLED_TB_Display_On[]={0x8d,0x14,0xaf};
const unsigned char OLED_TB_Display_Off[]={0x8d,0x10,0xae};
const unsigned char OLED_TB_Horizontal_Addressing_Mode[]={0x20,0x00};

void OLED_Reset_Pos(void) 
{ 
	m_OLED_WR_CMD(OLED_TB_Setup_column);//-Setup column start and end address 
	m_OLED_WR_CMD(OLED_TB_Setup_page);//Setup page start and end address
}
//开启OLED显示    
void OLED_Display_On(void)
{
	m_OLED_WR_CMD(OLED_TB_Display_On);
}
//关闭OLED显示     
void OLED_Display_Off(void)
{
	m_OLED_WR_CMD(OLED_TB_Display_Off);
}		   			 
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	  
void OLED_Clear(void)  
{  
	
	unsigned char i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_Set_Pos(0,i);
		OLED_DAT_CS();
		for(n=0;n<128;n++)
		{
			OLED_WR_Byte(0); 
		}
		OLED_CS_Set();
	} //更新显示
}

/***********功能描述：显示显示BMP图片128×64起始点坐标(x,y),x的范围0～127，y为页的范围0～7*****************/
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{ 	
	unsigned int j=0;
	unsigned char x,y;
  
	if(y1%8==0)
	{
		y=y1/8;
	}
	else
	{
		y=y1/8+1;
	}
	for(y=y0;y<y1;y++)
	{
		OLED_Set_Pos(x0,y);
		OLED_DC_Set();		  
		OLED_CS_Clr();
		for(x=x0;x<x1;x++)
	    {      
			OLED_WR_Byte(BMP[j++]);
	    }
		OLED_CS_Set();
	}
} 

void OLED_Reflash(unsigned char *ch)
{ 	
	unsigned int i;
#ifdef OLED_MODE_PAGE
	for(i=0;i<8;i++)
	{
		OLED_Set_Pos(0,i);
		OLED_DC_Set();		  
		OLED_CS_Clr();
//		for(j=0;j<128;j++)
//	    {      
//			OLED_WR_Byte(*ch++);
//	    }
		OLED_WR_Buf(ch,128);
		ch += 128;
		OLED_CS_Set();
	}
#else
	OLED_Reset_Pos();
	OLED_DC_Set();		  
	OLED_CS_Clr();
	for(i=0;i<128*8;i++)
	{
		OLED_WR_Byte(*ch++);
	}
	OLED_CS_Set();
#endif
}

const unsigned char OLED_TB_Reset[]=
{
	0xAE,//--turn off oled panel,AE:turn off,AF turn on
	0x02,//---set low column address
	0x10,//---set high column address
	0x40,//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	0x81,//--set contrast control register
	0xCF, // Set SEG Output Current Brightness
	0xA1,//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	0xC8,//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	0xA6,//--set normal display
	0xA8,//--set multiplex ratio(1 to 64)
	0x3f,//--1/64 duty
	0xD3,//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	0x00,//-not offset
	0xd5,//--set display clock divide ratio/oscillator frequency
	0x80,//--set divide ratio, Set Clock as 100 Frames/Sec
	0xD9,//--set pre-charge period
	0xF1,//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	0xDA,//--set com pins hardware configuration
	0x12,
	0xDB,//--set vcomh
	0x40,//Set VCOM Deselect Level
	
//	0x20,//-Set Page Addressing Mode (0x00/0x01/0x02)		//SH1106只有页模式
//	//0x02,//每行结束不移到下一行,Page Addressing Mode (RESET)
//	0x00,//每行结束移到下一行,Horizontal Addressing Mode
//	
//	0x21,//-Setup column start and end address 
//	0,//Column start address, range : 0-127d(RESET = 0d)
//	127,//Column end address, range : 0-127d(RESET = 127d)
//	
//	0x22,//Setup page start and end address
//	0,//Page start Address, range : 0-7d(RESET = 0d)
//	7,//Page end Address, range : 0-7d,(RESET = 7d)
	
	
	
	0x8D,//--set Charge Pump enable/disable
	0x14,//--set(0x10) disable
	
	0xA4,// Disable Entire Display On (0xa4/0xa5)
	0xA6,// Disable Inverse Display On (0xa6/a7) 
	0xAF//--turn on oled panel
};




//初始化SSD1306					    
void OLED_Init(void)
{ 	 
	OLED_RST_Set();
	delay_us(100000);
	OLED_RST_Clr();
	delay_us(100000);
	OLED_RST_Set(); 
						  
	m_OLED_WR_CMD(OLED_TB_Reset);//--turn off oled panel,AE:turn off,AF turn on
	//m_OLED_WR_CMD(OLED_TB_Horizontal_Addressing_Mode);//SH1106只有页模式
	//OLED_Reset_Pos();
	//OLED_Clear();	
}  





























